package com.example.config.handler.login.sms;

import com.example.config.handler.login.ClientUserDetails;
import com.example.config.handler.login.UserLoginInfo;
import com.example.config.handler.login.User;
import com.example.config.handler.login.username.UsernameAuthentication;
import com.example.model.api.Result;
import com.example.redis.RedisUtils;
import com.example.service.UserService;
import com.example.utils.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

@Component
public class SmsAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  private UserService userService;

  @Autowired
  private RedisUtils redisUtils;

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    if (!(authentication instanceof SmsAuthentication)) {
      return null; // 不支持的 token 类型
    }
    SmsAuthentication smsAuthentication = (SmsAuthentication) authentication;

    // 验证验证码是否正确
    if (validateSmsCode(smsAuthentication.getPhone(), smsAuthentication.getSmsCode())) {
      // 根据手机号查询用户信息
      ClientUserDetails clientUserDetails = userService.getUserByPhone(smsAuthentication.getPhone());
      if (clientUserDetails == null) {
        throw new BadCredentialsException("${user.not.found:找不到用户!}");
      }

      SmsAuthentication token = new SmsAuthentication(clientUserDetails.getAuthorities());
      token.setCurrentUser(clientUserDetails);
      token.setAuthenticated(true); // 认证通过，一定要设成true
      return token;
    } else {
      throw new BadCredentialsException("${verify.sms.code.fail:验证码不正确！}");
    }
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return SmsAuthentication.class.isAssignableFrom(authentication);
  }

  private boolean validateSmsCode(String phone, String smsCode) {
    String codeKey = "phoneCode:" + phone;
    String val = (String) redisUtils.get(codeKey);
    if (smsCode == null || val == null) {
      throw new BadCredentialsException("验证码不存在");
    }
    return smsCode.equals(val);
  }
}